package com.bjpowernode.services;

import com.bjpowernode.beans.Stu;
import com.bjpowernode.compare.StuAgeCompare;
import com.bjpowernode.compare.StuIdCompare;
import com.bjpowernode.compare.StuScoreCompare;
import com.bjpowernode.compare.StuSexCompare;
import com.bjpowernode.dao.StuDao;
import com.bjpowernode.dao.StuDaoImp;
import com.bjpowernode.exception.MyNumberException;

import java.util.*;

public class StuServicesImp implements StuServices {
    StuDao stuDao = new StuDaoImp();
    //学生ID生成器
    //1——不能重复
    //2——1000-9000
    //技术选型：TreeSet
    //TreeSet实现缓存1000-9000这些数（相当于ID池）
    //添加的时候从TreeSet的第一个元素取出来（取出来的含义就是TreeSet集合的第一个元素要删除）,为自动生成的ID
    //删除的时候把选择的学生ID，在放回到TreeSet里面去，利用TreeSet自动排序规则，进行排序
    //TreeSet是需要比较器的，但是学生ID是整数，整数已经实现了比较器，则我们无需自己实现比较器
    private static TreeSet<Integer> ids = new TreeSet<>();

    //TreeSet初始化
    static {
        //初始化缓存1000-9000
        for (int i = 1000; i <= 9000; i++) {
            ids.add(i);
        }
    }


    //业务需要返回生成的ID
    public int autoID() {
        return ids.pollFirst();
    }

    @Override
    public int lookID() {
        return ids.first();
    }

    //删除的时候把ID还给我
    public void flybackID(int id) throws MyNumberException {
        //返回ID的时候，需要判断
        //不能超标
        if (id < 1000 || id > 9000) {
            throw new MyNumberException("ID返回超标");
        }
        //不能我里面有的
        boolean contains = ids.contains(Integer.valueOf(id));
        if (contains) {
            throw new MyNumberException("ID返回异常，因为都没有分配出去");
        }
        //可以添加
        ids.add(id);
    }


    @Override
    public ArrayList<Stu> getAll() {
        return stuDao.getAll();
    }

    //***************************比较器系列******************************
    private ArrayList<Stu> sortTools(Comparator<Stu> stuComparator) {
        //业务调用自己的查询所有，然后生成一个新集合
        ArrayList<Stu> stus = new ArrayList<>(getAll());
        //对新集合排序
        Collections.sort(stus, stuComparator);
        //返回新集合
        return stus;
    }

    @Override
    public ArrayList<Stu> sortById() {
        return sortTools(new StuIdCompare());
    }

    @Override
    public ArrayList<Stu> sortBySex() {
        return sortTools(new StuSexCompare());
    }

    @Override
    public ArrayList<Stu> sortByAge() {
        return sortTools(new StuAgeCompare());
    }

    @Override
    public ArrayList<Stu> sortByScore() {
        return sortTools(new StuScoreCompare());
    }

    @Override
    public HashSet<Stu> getRandomStu(int numCount) throws MyNumberException {
        //利用HashSet判断重复的特点，进行去重
        HashSet<Stu> stus = new HashSet<>();
        int size = getAll().size();
        //判定随机总数（即为随机总人数）是否符合要求
        if (numCount <= 0 || numCount > size) {
            throw new MyNumberException("输入的随机点名数量不符合规范");
        }
        //开始获取随机学员
        Random random = new Random();
        //ctrl+alt+键盘上的左右
        //numCount参数实际是随机的次数
        while (true) {
            //随机下标
            int i = random.nextInt(size);
            //随机抽到了一个学生
            Stu stu = getAll().get(i);
            //进入HashSet集合
            stus.add(stu);
            //numCount参数实际是随机的次数
            if (stus.size() == numCount) {
                break;
            }
        }
        return stus;
    }


    @Override
    public boolean add(Stu stu) throws MyNumberException {
        //也许需要判断分数
        float score = stu.getScore();
        //分数判断范围
        if (score < 0 || score > 100) {
            throw new MyNumberException("分数范围为0-100");
        }

        //学生的各个属性的具体值是否符合要求，由界面判断（控制器）
        //这里需要判定ID是否重复
        //这里正式设置ID


        stu.setId(autoID());
        stuDao.add(stu);


        return true;
    }

    @Override
    public boolean del(Stu stu) throws MyNumberException {
        //事务：一件事由N个流程组成，任意流程出问题，则可以回滚
        //stu集合要删除
        stuDao.del(stu);
        //stu使用的ID需要返还给TreeSet
        flybackID(stu.getId());
        return true;
    }

    @Override
    public boolean edit(Stu stu) throws MyNumberException {
        //什么都不做
        return true;
    }
}
